package com.me.study.javaCore.agent;

import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Java Agent 技术 222：    <p>
 *   运行时，通过 attach API将模块（jar包）动态地 Attach到指定 PID 的 Java进程内     <p>
 *      attach 方法见：com.me.study.javaCore.agent.Attacher
 *
 * @author ME
 */
public class AttachAgent {

    /** 是否已附加 */
    private static AtomicBoolean attached = new AtomicBoolean(false);

    public static void agentmain(String agentArgs, Instrumentation inst) {
        System.out.println("\nattach agent 接收到的参数：" + agentArgs);
        System.out.println();

        final MyTransformer transformer = new MyTransformer();
        // TODO 每次都会重新注册 ClassFileTransformer，会导致类增强多次
        if (attached.compareAndSet(false, true)) {
            inst.addTransformer(transformer, true);
        }

        try {
            // TODO: TransformTarget类 主动触发 MyTransformer#transform
            for (Class<?> clazz : inst.getAllLoadedClasses()) {
                if ("com.me.study.javaCore.agent.TransformTarget".equals(clazz.getName())) {
                    // inst.retransformClasses(TransformTarget.class);
                    inst.retransformClasses(clazz);
                }
            }

            System.out.println("attach agent 加载完毕");
        } catch (UnmodifiableClassException e) {
            e.printStackTrace();
        } finally {
            inst.removeTransformer(transformer);
        }
    }

}
